//
// The resource management layer has been upgraded, thus deprecating this file.
//
#error *** resentry.cpp has been deprecated. ***

#include <stdlib.h>
#include <string.h>

#include "lib.h"
#include "resfile.h"
#include "resentry.h"

#if defined(DEBUG_CRESENTRY)
#	include "endian.h"
#endif


pCResEntry
newCResEntry(RFEntry * FileEntry, uint32 ResGrp)
{
	pCResEntry	resentry = (pCResEntry)malloc(sizeof(CResEntry));

	if (resentry)
		CResEntryConstruct(resentry, FileEntry, ResGrp, false);

	return resentry;
}

pCResEntry
newCCompressedResEntry(RFCompressedEntry * FileEntry, uint32 ResGrp)
{
	pCResEntry	resentry = (pCResEntry)malloc(sizeof(CResEntry));

	if (resentry)
		CResEntryConstruct(resentry, (RFEntry *)FileEntry, ResGrp, true);

	return resentry;
}


void
deleteCResEntry(pCResEntry This)
{
	if (This)
	{

#if defined(DEBUG_CRESENTRY)
		if (This->cMagic != RESENTRY_MAGIC)
		{
			DEBUGMSG(("deleteCResEntry(): Invalid cMagic field!."));
			return;
		}

		if (This->cUseCount != 0)
		{
			DEBUGMSG(("deleteCResEntry(): Deletion of '%s' with a non-zero"
				" use count '%d'.", This->cName, This->cUseCount));
		}
#endif

		CResEntryDestruct(This);
		free(This);
	}
}


void
CResEntryConstruct(pCResEntry This, RFEntry * FileEntry, uint32 ResGrp, bool8 compressed)
{
	This->cOffset	= FileEntry->cOffset;
	This->cSize		= FileEntry->cSize;
	This->cUseCount	= 0;
	This->cData		= NULL;
	This->cUserData	= NULL;
	This->cCompressedSize = 0;
	if (compressed)
	{
		This->cCompressedSize = ((RFCompressedEntry*)FileEntry)->cCompressedSize;
	}


#if defined(DEBUG_CRESENTRY)
	This->cMagic	= RESENTRY_MAGIC;
#endif

#if defined(DEBUG_CRESENTRY) || defined(RESCOMPILER)
	strcpy((char *)This->cName,(char *)FileEntry->cName);
	This->cGroup	= ResGrp;
#endif
}


void
CResEntryDestruct(pCResEntry This)
{
	if (This->cData)
	{
#if defined(DEBUG_CRESENTRY)
		if (RESDATA(This->cData)->cMagic != RESDATA_MAGIC)
		{
			DEBUGMSG(("CResEntryDestruct(): Invalid cMagic field!."));
			return;
		}
#endif

		free(This->cData);
	}
}


void *
CResEntryGetData(pCResEntry This)
{
	void *	data = NULL;


#if defined(DEBUG_CRESENTRY)
	if (This->cMagic != RESENTRY_MAGIC)
	{
		DEBUGMSG(("CResEntryGetData(): Invalid cMagic field!."));
		return NULL;
	}
#endif

	if (This->cData != NULL)
	{
#if defined(DEBUG_CRESENTRY)
		if (RESDATA(This->cData)->cMagic != RESDATA_MAGIC)
			DEBUGMSG(("CResEntryGetData(): Invalid cMagic field!."));
#endif

		This->cUseCount++;
		data = ResDataData(This->cData);
	}

	return data;
}


bool8
CResEntryReleaseData(void * Data)
{
	pCResEntry	This = ResDataHeader(Data)->cRefPointer;


#if defined(DEBUG_CRESENTRY)
	if ((ResDataHeader(Data)->cMagic != RESDATA_MAGIC) ||
		(This->cMagic != RESENTRY_MAGIC))
	{
		DEBUGMSG(("CResEntryReleaseData(): Invalid cMagic field!."));
		return false;
	}
#endif

	if (This->cUseCount > 0)
	{
		This->cUseCount--;

		if (This->cUseCount == 0)
		{
			free(This->cData);
			This->cData = NULL;

			return true;
		}
	}
#if defined(DEBUG_CRESENTRY)
	else
	{
		DEBUGMSG(("CResEntryReleaseData(): Attempts were made to free a"
			" resource w/ use count of zero."));
	}
#endif

	return false;
}


void *
CResEntryAllocDataSpace(pCResEntry This)
{
#if defined(DEBUG_CRESENTRY)
	if (This->cMagic != RESENTRY_MAGIC)
	{
		DEBUGMSG(("CResEntryAllocDataSpace(): Invalid cMagic field!."));
		return NULL;
	}
#endif

	This->cData = malloc(This->cSize + sizeof(CResData));
	if (!This->cData)
		return (void *)0;

	// Update use count since we have allocated memory...
	This->cUseCount++;

	// Set the Reference pointer so we can get back to ourselves later.
	RESDATA(This->cData)->cRefPointer = This;
#if defined(DEBUG_CRESENTRY)
	RESDATA(This->cData)->cMagic = RESDATA_MAGIC;
#endif

	return ResDataData(This->cData);
}


// NOTE: The following two functions should not be abused!  If they are...
//       you could have serious memory leaks!!!!
void
CResEntrySetUserData(void * Data, void * UserData)
{
	pCResEntry	This = ResDataHeader(Data)->cRefPointer;

#if defined(DEBUG_CRESENTRY)
	if ((ResDataHeader(Data)->cMagic != RESDATA_MAGIC) ||
		(This->cMagic != RESENTRY_MAGIC))
	{
		DEBUGMSG(("CResEntrySetUserData(): Invalid cMagic field!."));
		return;
	}
#endif

	This->cUserData = UserData;
}


void *
CResEntryGetUserData(void * Data)
{
	pCResEntry	This = ResDataHeader(Data)->cRefPointer;

#if defined(DEBUG_CRESENTRY)
	if ((ResDataHeader(Data)->cMagic != RESDATA_MAGIC) ||
		(This->cMagic != RESENTRY_MAGIC))
	{
		DEBUGMSG(("CResEntryGetUserData(): Invalid cMagic field!."));
		return NULL;
	}
#endif

	return This->cUserData;
}


uint32
CResEntryQueryUseCount(void * Data)
{
	pCResEntry	This = ResDataHeader(Data)->cRefPointer;

#if defined(DEBUG_CRESENTRY)
	if ((ResDataHeader(Data)->cMagic != RESDATA_MAGIC) ||
		(This->cMagic != RESENTRY_MAGIC))
	{
		DEBUGMSG(("CResEntryQueryUseCount(): Invalid cMagic field!."));
		return 0;
	}
#endif

	return This->cUseCount;
}


//----------------------------------------------------------------------------
//  What applications can do with the resource data they have...
//
uint32
CResDataSize(void * ResData)
{
	pCResEntry	This = ResDataHeader(ResData)->cRefPointer;

	return CResEntrySize(This);
}


//----------------------------------------------------------------------------
//  Everything below this line has been written specifically for the 
//     Resource Compiler.
//
#if defined(RESCOMPILER)
pCResEntry
newCResEntryWithData(char * ResName, uint32 ResGrp, void * ResData, 
	uint32 Length)
{
	pCResEntry	resentry = (pCResEntry)calloc(sizeof(CResEntry), 1);

	if (resentry)
		CResEntryConstructWithData(resentry, ResName, ResGrp, ResData, Length);

	return resentry;
}


void
CResEntryConstructWithData(pCResEntry This, char * ResName, uint32 ResGrp,
	void * ResData, uint32 Length)
{
	This->cOffset	= 0;
	This->cData		= malloc(Length + sizeof(CResData));
	This->cGroup	= ResGrp;
	This->cUserData	= NULL;
	This->cUseCount	= 0;		// Nobody is really...'using'...it.

#if defined(DEBUG_CRESENTRY)
	This->cMagic	= RESENTRY_MAGIC;
#endif

	if (strlen(ResName) >= resfileNAME_LENGTH)
	{
		DEBUGMSG(("CResEntryConstructWithData():  !TRUNCATION WARNING!\n"    \
			"    ResName '%s' is greater than allowed length of %d bytes.",  \
			ResName, resfileNAME_LENGTH - 1));

		// We have to modify the source name so it is registered with the
		//    hashtable correctly...
		ResName[ resfileNAME_LENGTH - 1 ] = '\0';
	}

	strcpy((char *)This->cName, (char *)ResName);

	if (This->cData)
	{
		This->cSize = Length;

		// Set the reference pointer.
		RESDATA(This->cData)->cRefPointer = This;

#if defined(DEBUG_CRESENTRY)
		RESDATA(This->cData)->cMagic = RESDATA_MAGIC;
#endif

		// Copy ResData
		memcpy(ResDataData(This->cData), ResData, Length);
	}
	else
	{
		// We have a serious problem if we ever get here.
		This->cSize = 0;
		DEBUGMSG(("CResEntryConstructWithData(): Serious problem!!!"));
	}
}
#endif

